Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Does STATA behave differently if we use conditional statements "if abc {execute code} VERSUS "do xyz if abc" statements in a loop

    Hello, data example below: I have one row per ID, the baseline date (BSDATE), and the date until which they are followed (FUuntil)
    Code:
    * Example generated by -dataex-. For more info, type help dataex
    clear
    input float id long BSDATE float FUuntil
      1 8886 12768
      2 8873  9742
      3 8868 12744
      4 8866 21662
      5 8883 11760
      6 8862 20045
      7 8862 20315
      8 8889 11933
      9 8861  9713
     10 8872 12715
    end
    format %td BSDATE
    format %td FUuntil
    I wrote the following code to create some wide variables for each person (if a person is followed from 4jan1990 to 5sept1992, i would want them to have 3 "from" and "to" date pair variables as follows:
    dfrom1= 4 jan 1990; dto1=31Dec1990
    dfrom2= 1jan1991; dto2=31dec1991
    dfrom3=1jan1992; dto3=5sept1992

    but it wasnt working how i wanted it to. [PS: i looped 36 times as the largest # years of follow up is 36]


    Code:
    sum FUtime //36
    gen curryear=year(BSDATE)
    foreach x of numlist 1/36 {
        gen dfrom`x'=.
        if curryear==year(BSDATE){
            replace dfrom`x'=BSDATE
        }
        else if curryear>year(BSDATE) & !mi(curryear) & curryear<=year(FUuntil) {
            replace dfrom`x'=mdy(1,1,curryear)
        }
        gen dto`x'=.
        if curryear<year(FUuntil){
            replace dto`x' =mdy(12,31,curryear)
        }
        else if curryear==year(FUuntil){
            replace dto`x'=FUuntil
        }
        format dfrom`x' %td
        format dto`x' %td
        dis curryear
        replace curryear=curryear+1
    }

    But when i changed it to this it worked.
    Code:
    gen curryear=year(BSDATE)
    foreach x of numlist 1/36 {
        gen dfrom`x'=.
        replace dfrom`x'=BSDATE if curryear==year(BSDATE)
        replace dfrom`x'=mdy(1,1,curryear) if curryear>year(BSDATE) & !mi(curryear) & curryear<=year(FUuntil)
        gen dto`x'=.
        replace dto`x' =mdy(12,31,curryear) if curryear<year(FUuntil)
        replace dto`x'=FUuntil if curryear==year(FUuntil)
        format dfrom`x' %td
        format dto`x' %td
        dis curryear
        replace curryear=curryear+1
    }
    Not sure what i was doing wrong the first time? the structured code like that really helps me think more clearly, so i was bummed that i had to convert it to the other type of conditional in order for it to work..would appreciate any help!!
    Last edited by Sakshi Rajatbhai Tewari; 18 Jul 2022, 12:01.

  • #2
    In the first code example, you use if statements with code blocks. What you are saying in natural language is "if and only if the following expression evaluates to true, run the following code block." But it looks like you actually want to compare a constant to a vector, and the expression should be true for some observations and false for others, but the code block syntax assumes you have an expression that evaluates to a single true or false value. If that single value is true, do what is in the code block, otherwise do not do what is in the code block. On the other hand, "replace var if expression" will look at each observation and replace the observation if the expression holds for the same observation.

    EDIT: Another comment on the if else statement: the -else if- statement should only run if the -if- statement is false. Once again, you should think of these code blocks as mutually exclusive conditions over iterations of your loop, not over observations. So if on iteration 1 of your loop, the -if- statement evaluates to true, the -else if- statement will not run. If on the second iteration the -if- statement evaluates to false, the -else if- statement might run if the corresponding expression evaluates to true.
    Last edited by Daniel Schaefer; 18 Jul 2022, 12:29.

    Comment


    • #3
      Commands like

      Code:
      if curryear==year(BSDATE)
      mentioning variables (meaning, strictly, columns in your dataset) will be interpreted as referring to the first observation (row) of a variable (only)

      Code:
      if curryear[1]==year(BSDATE[1])
      Stata won't look at every or indeed any observation beyond the first. That is what the if qualifier does.

      ttps://www.stata.com/support/faqs/p...-if-qualifier/ is an FAQ on this, although to my mind it is backwards, the question there is more nearly the answer, and the question is more often Why is the if command not working as I expect?

      See also https://www.statalist.org/forums/help#spelling

      Comment


      • #4
        Originally posted by Daniel Schaefer View Post
        Once again, you should think of these code blocks as mutually exclusive conditions over iterations of your loop, not over observations. So if on iteration 1 of your loop, the -if- statement evaluates to true, the -else if- statement will not run. If on the second iteration the -if- statement evaluates to false, the -else if- statement might run if the corresponding expression evaluates to true.
        This drove it home for me i think- thank you! will read this again and again till it cements in my brain

        Comment


        • #5
          Originally posted by Nick Cox View Post
          Commands like

          Code:
          if curryear==year(BSDATE)
          mentioning variables (meaning, strictly, columns in your dataset) will be interpreted as referring to the first observation (row) of a variable (only)

          Code:
          if curryear[1]==year(BSDATE[1])
          Stata won't look at every or indeed any observation beyond the first. That is what the if qualifier does.

          ttps://www.stata.com/support/faqs/p...-if-qualifier/ is an FAQ on this, although to my mind it is backwards, the question there is more nearly the answer, and the question is more often Why is the if command not working as I expect?

          See also https://www.statalist.org/forums/help#spelling
          Thank you Nick! i will check out the FAQ..i'll study the difference between the two syntax in depth too

          Comment

          Working...
          X